<html>
<head>
  <title>CWListCore - List Windows</title>
</head>
<body bgcolor="white" text="black">
<h1 align="center">CWListCore</h1>

<p>The purpose of CWListCore is to handle windows containing a list of items (and only that). Such a window is composed of a background and of items plotted in the foreground.</p>

<h2 align="left">The window background</h2>

<p>The background can be one of the standard window backgrounds or a user defined background plotted by a callback set with <code>WListCore_SetFPlotBackGround</code>. In the latest case, set the standard window background to transparent to avoid needless redraw. Also, to speed up the redraw WListCore asserts that items plot their own background and will not plot the background on the area covered by the items. To change this behaviour set the <code>EWList_Transparent</code> flag.</p>

<h2 align="left">List Items</h2>

<p>The list items are plotted starting by default on the top-left corner of the window, from left to right and from top to bottom, in a single column and with the window size growing vertically as more items are added to the list. Flags can be set to alter this behaviour either at the creation of the list or later (by using the <code>WListCore_SetFlags</code> function). In multiple columns (rows) mode, the number of columns (rows) depends of the width (height) of the items and of the width (height) of the window visible area/extent.</p>

<h3 align="left">Size of the list items</h3>

<p>Each item will be plotted with the same cell size, which is the smallest size in which any item of the list can be displayed. If you think a little bit to the latest sentence you will see that it doesn't always mean to find the larger item and the highest item of the list. The size of an item depends of a given number of characteristics, which are not always the width and height nor are always 2.</p>

<p>For example:</p>
<ul>
  <li>in text lists:
    <br>n = 1 (tx = width of plotted text)
    <br>width = 4 + txmax + 4
    <br>height = 40
  </li>
  <li>in filers:
    <br>n = 3 (tx = width of plotted text, sx = sprite width, sy = sprite height)
    <br>width = 4 + max(txmax, sxmax) + 4
    <br>height = 4 + 40 + 8 + symax + 4
  </li>
  <li>in lists such as for the mailbox of exchange:
    <br>n = 4 (fx = width of text for 'from' column, sx = width for 'send' column, rx = ... 'received', ssx = 'size')
    <br>width = fxmax + sxmax + rxmax + ssxmax
    <br>height = 40
  </li>
</ul>

<p>In short, the size at which items are plotted depends on n characteristics, for each of these characteristics you have to find the largest value among the list, then on basis on these maximum values you can compute the size for plotting. This is how WListCore works and requires that you define at the creation of the list: the number of characteristics required, a callback that will fill these characteristics for a given item and another callback that will return the cell size on basis on the maximum value of each characteristic.</p>

<h3 align="left">Plotting the list items</h3>

<p>WListCore controls how list items are organised and where items are plotted within the window. So, all WListCore requires is that you define at the creation of the list a callback that will plot items. This function receives as parameters a pointer to the item to plot, the rectangle where to plot the item, its size characteristics, the corresponding maximum values (useful for aligning item parts), the item index and flags to modify the aspect of the item:</p>

<ul>
  <li><code>EWListItem_Selected</code>: obvious.</li>
  <li><code>EWListItem_Inverted</code>: used during mouse dragging to mark that the selection status of this item will change when the dragging is validated.</li>
  <li><code>EWListItem_HasFocus</code>: this item has the focus, a dotted rectangle which acts in the same way as a cursor for text.</li>
</ul>

<h2 align="left">Selection handling</h2>

<p>WListCore sends a <code>wimp_EListChange</code> event to the window given has parent window at the creation of the list.</p>

<p>The event has the following structure:</p>
<pre><code>
struct CEvent_ListChange
{
        wimp_etype      e;
        void*           pWList; /* I used void for easy casting */
        int             Index;
};
</code></pre>

<p>with Index returning the index of the selected item if only one is selected or '-1' in any other case.</p>

<h2 align="left">Keyboard handling</h2>

<p>WListCore intercepts the following keys: the Ins key to switch between various operating modes and arrows, Page Up and PageDown to move the focus. All other keys can be used by your own window handlers.</p>

<h3 align="left">Focus movement</h3>

<ul>
  <li>Arrows move the focus to the next item in the given direction</li>
  <li>Shift + Arrows move the focus to the next page of item in the given direction</li>
  <li>Ctrl + Arrows move the focus to farthest item in the given direction</li>
  <li>Page Up moves the focus one page up</li>
  <li>Page Down moves the focus one page down</li>
</ul>

<h3 align="left">Operating modes</h3>

<p>Pressing the Ins key toggles follow mode on or off:</p>

<ul>
  <li>Follow mode (the default mode): when the focus moves, selection is reset to the item owning the focus.</li>
  <li>Non Follow mode: when the focus moves, the selection is not altered. This allows scrolling within the list without altering the selection.</li>
</ul>

<p>Pressing Ctrl and/or Shift + Ins for a list which allows multiple selection enters a selection mode and marks the item who owns the focus as start of group. The action started will depend of the key combination used:</p>

<ul>
  <li>Shift + Ins: Clear current selection and select a group of items</li>
  <li>Ctrl + Ins: Invert selection status of a group of items</li>
</ul>

<p>Once in such a mode, move the focus to the item that will mark the end of item group and repeat the key combination to complete the action, or press Esc to cancel the action.</p>

<h2 align="left">Mouse handling</h2>

<p>By default CWListCore does only one thing: set the focus in the window when clicked with ADJUST on the window if the window does not have the focus. Additional actions can be provided by registering new event handlers for the window.</p>

<p>CWListcore provides the function <code>WListCore_ItemAndActionFromScreenPt</code> which will help you handle mouse clicks: it will return you the index of the item on which the pointer stands (or -1 if none) and an area number.</p>

<h3 align="left">Item index and Item areas</h3>

<p>The item index is obvious, so let us explain the area number concept. CWListCore let you divide the screen rectangle containing your item in areas: the two first ones being the <code>EWListItem_OutsideArea</code> and the <code>EWListItem_ActiveArea</code>. All the other areas are called Inactive areas.</p>

<p>Let us consider the example of a filer window that display for each file its icon, its name and toggles for its access settings: if you click on the item text or sprite you will select the object, if you click on any of the toggles it will invert the corresponding toggle and if you click anywhere else the current selection will be cleared.</p>

<p>The item's text and sprite form the Active area: an area which will allow you to select the item, to drag it or to double-click on it. Each toggle forms an Inactive area: acting on it only affects properties of the item, but has no effect on the selection status of items. Finally the other parts form the Outside area, an area considered as if you clicked outside the item.</p>

<p>The default behaviour of CWListcore is to consider every part of the item rectangle has an Active area. To alter this behaviour you will have to register a callback with <code>WListCore_SetFGetItemArea</code>. When called the callback will receive the same parameters as the callback used for plotting the item, the position of the click within the plotted rectangle (given as an offset from the bottom left corner of this rectangle) and the mouse buttons used for the click. On exit the callback must return the number of the area clicked.</p>

<h3 align="left">The WListCore_ListEventHandler</h3>

<p>This is an event handler you can register as follow:</p>

<pre><code>
Window_RegisterEventHandler(WListCore_GetWindow(pListCore)
                          , WListCore_ListEventHandler
                          , pListCore
                          , false);
</code></pre>

<p>It will provide you the behaviour of standard text lists but still let you handle mouse events it does not treat itself.</p>

<ul>
  <li>If the pointer is on no item on or on the Outside area of an item nothing is done, the event is returned as proccessed.</li>
  <li>Click/drag with SELECT on the active area of an unselected item will clear any previous selection and start the selection of a range of items, the event is returned as proccessed.</li>
  <li>Click/drag with ADJUST on an active area will preserve the current selection and invert the selection status of a range of items, the event is returned as proccessed.</li>
  <li>In every other case the event is returned as unprocessed and given to the next event handler.</li>
</ul>

<h2 align="left">CWListCore creation</h2>

<p>A CWListCore object must be initialised with the function WListCore_WListCore.</p>

<ul>
  <li>The layout flags
    <p>The layout of items in the window is a table. The default is a table filled row by row, from top to bottom and from left to right, with only one item by row. This also means that the table grows (shrinks) vertically as more items are added (removed) from the list. The following flags can alter this behaviour:</p>
    <ul>
      <li>EWList_MultiColumn: allows the items to be displayed in has many rows (columns) as the width (height) of the window extent permits.</li>
      <li>EWList_GrowHorz, the table is filled column by column and the table grows (shrinks) horizontally as more items are added (removed) from the list.</li>
      <li>EWList_RightToLeft, the table is filled from right to left.</li>
      <li>EWList_BottomToTop, the table is filled from the bottom to the top.</li>
      <li>EWList_FitVisibleArea, the number of items in a row (column) is fixed by the width (height) of the window visible area (instead of the extent).</li>
    </ul>
  </li>
  <li>Other flags
    <ul>
      <li>EWList_MultiSel, allows to select more than one item in the list.</li>
      <li>EWList_Popup, marks the window as being used as a popup menu preventing CWListCore to make Wimp_OpenWindow that would cause the window not to close when the user clicks outside of it. As a side effect, the focus is never set and keyboard operations are not possible.</li>
      <li>EWList_NoFocus, prevents the focus to be set and disallow keyboard operations.</li>
      <li>EWList_Transparent, marks the list items as transparent and requiring the window background to be redrawn before items are plotted.</li>
      <li>EWList_FilerExtent, should be used combined to EWList_FitVisibleArea, forces the window to have the same behaviour as a filer window when the window is resized.</li>
    </ul>
  </li>
</ul>
<pre><code>
void WListCore_WListCore( CWListCore* this
                        , EWListCore_Flags flags
                        , wimp_wind* pinfo
                        , wimp_w parentwnd
                        , wimp_box RectToFit
                        , void* pHandle
                        , int NrSizes
                        , FWList_GetItemBox pGetItemBox
                        , FWList_GetItemSize pGetItemSize
                        , FWList_PlotItem pPlotItem
                        );
</code></pre>
</body>
</html>